/**********************************************************************************************/
/* FBL_Macros.h 	                                                      					  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006															  */
/* All Rights Reserved                                                   					  */
/**********************************************************************************************/

#ifndef _FBL_Macros_h 
	#define _FBL_Macros_h
#pragma once


/**********************************************************************************************/
//	std Namespace

	// Macro for controlling use of "std" namespace for the C++ standard libraries.
	// Set to OFF only if you have explicitly disabled namespace support
	// in the MSL or are using another implementation of the C++
	// standard libraries that does not support namespaces.

#ifndef Uses_Std_Namespace
	#define	Uses_Std_Namespace			1
#endif

#if Uses_Std_Namespace
	#define Std_Begin_Namespace			namespace std {
	#define Std_End_Namespace			}
	#define Std_Using_Namespace			using namespace std;
	#define STD std
#else
	#define Std_Begin_Namespace			
	#define Std_End_Namespace			
	#define Std_Using_Namespace
	#define STD
#endif


// open namespaces for use in the sources of Kernel
//namespace std {}
//Std_Using_Namespace


/**********************************************************************************************/
//	FBL Namespaces.
// 	This is a namespace of kernel interfaces and kernel implementation of low (relational) level.

#ifndef Uses_Namespace
	#define Uses_Namespace				1
#endif

#if Uses_Namespace
	#define FBL_Begin_Namespace			namespace fbl {
	#define FBL_End_Namespace			}
	#define FBL_Using_Namespace			using namespace fbl;
	#define FBL							fbl
#else
	#define FBL_Begin_Namespace
	#define FBL_End_Namespace
	#define FBL_Using_Namespace
	#define FBL
#endif


/**********************************************************************************************/
// Open-close namespaces, so compiler become awere about it.
FBL_Begin_Namespace		
FBL_End_Namespace

// Open FBL namespaces for use in the sources of Kernel.
// FBL_Using_Namespace


/**********************************************************************************************/
//									*** MACROS ***
/**********************************************************************************************/
#if defined(__MWERKS__)
// CodeWarrior C/C++ from Metrowerks, Inc.

#if macintosh || TARGET_OS_MAC
	#define FBL_MAC 		1 
	#define FBL_WIN 		0
	#define FBL_UNIX 		0

	#if __MACH__
	#define FBL_MAC_MACHO	1
	#define FBL_MAC_CARBON	0
	#else 
	#define FBL_MAC_MACHO	0
	#define FBL_MAC_CARBON	1
	#endif // __MACH__

#elif __INTEL__
	#define FBL_MAC 		0 
	#define FBL_MAC_MACHO 	0
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		1
	#define FBL_UNIX 		0

#elif __MIPS__
	#define FBL_MAC 		0 
	#define FBL_MAC_MACHO 	0
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		0
	#define FBL_UNIX 		1
#else
	#error "Not recognized target for CodeWarrior."
#endif

#endif // __MWERKS__


/**********************************************************************************************/
#if  defined(_MSC_VER) && !defined(__MWERKS__) 
// Visual Studio C/C++ from Microsoft, Inc.
#if defined(_M_IX86)
	#define FBL_MAC 		0 
	#define FBL_MAC_MACHO 	0
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		1
	#define FBL_UNIX 		0
#else
	#error "Not recognized target for Visual C++."
#endif // _M_IX86

#endif //defined(_MSC_VER) && !defined(__MWERKS__) 


/**********************************************************************************************/
#if defined(__GNUC__) && (defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__NEXT_CPP__))
// gcc based compilers used on OpenStep -> Rhapsody -> Mac OS X
	#define FBL_MAC 		1 
	#define FBL_MAC_MACHO 	1
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		0
	#define FBL_UNIX 		0
#endif // defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__NEXT_CPP__)


#if defined(__GNUC__) && defined(__MINGW32__)
// Mingw gnu gcc/egcs compiler for Win32 systems (http://www.mingw.org).
	#define FBL_MAC 		0 
	#define FBL_MAC_MACHO 	0
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		1
	#define FBL_UNIX 		0
#endif // defined(__GNUC__) && defined(__MINGW32__)


#if defined(__GNUC__)
// gC for MPW from Free Software Foundation, Inc.
#if  #system(macos)
	#define FBL_MAC 		1 
	#define FBL_MAC_MACHO 	1
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		0
	#define FBL_UNIX 		0
#elif  #system(unix)
	#define FBL_MAC 		0 
	#define FBL_MAC_MACHO 	0
	#define FBL_MAC_CARBON	0
	#define FBL_WIN 		0
	#define FBL_UNIX 		1
#endif // #system
#endif // __GNUC__



/**********************************************************************************************/
// this is TRUE if target is MACHO or UNIX, so we use POSIX API for files, threads, ...
//
#define FBL_POSIX_API (FBL_MAC_MACHO || FBL_UNIX)


/**********************************************************************************************/
// For FBL_MAC we need to check if this is INTEL mac. 
//
#if FBL_MAC
	#if __LITTLE_ENDIAN__
		#define FBL_INTEL_CPU 1
	#else 
		#define FBL_INTEL_CPU 0
	#endif //__LITTLE_ENDIAN__
#endif // FBL_MAC	

/**********************************************************************************************/
#if FBL_WIN
#define FBL_BIG_ENDIAN		0
#define FBL_LITTLE_ENDIAN	1
#elif FBL_MAC
#if FBL_INTEL_CPU
#define FBL_BIG_ENDIAN		0
#define FBL_LITTLE_ENDIAN	1
#else
#define FBL_BIG_ENDIAN		1
#define FBL_LITTLE_ENDIAN	0
#endif //FBL_INTEL_CPU
#elif FBL_UNIX		// KP We work now just on i386 CPU on linux
#define FBL_BIG_ENDIAN		0
#define FBL_LITTLE_ENDIAN	1
#endif // FBL_WIN


/**********************************************************************************************/
// macro for emulate "interface" keyword in the C++ language.
#ifdef interface
#	undef interface
#endif // interface

#define interface struct

/**********************************************************************************************/
#ifndef FBL_LENGTH
#	define FBL_LENGTH 64 	
#endif	


/**********************************************************************************************/
// Smart pointer for Valentina kernel.
// We use on default BOOST intrusive pointer.
//
#define SMART_PTR(ptr_class, name)\
	typedef ptr_class<name> name##_Ptr 

#define CONST_SMART_PTR(ptr_class, name)\
	typedef ptr_class<const name> Const_##name##_Ptr 

#define FULL_SMART_PTR(ptr_class, name)	\
	SMART_PTR(ptr_class, name);\
	CONST_SMART_PTR(ptr_class, name)

#define FBL_SMART_PTR(name)	\
	FULL_SMART_PTR( FBL::smart_ptr, name )

#define SMART_INTERFACE(name) 	\
	interface name; 			\
	FBL_SMART_PTR(name)

#define SMART_CLASS(name) 		\
	class name; 				\
	FBL_SMART_PTR(name)

#define SMART_STRUCT(name) 		\
	struct name; 				\
	FBL_SMART_PTR(name)

#define SMART_VALUE_INTERFACE(name) 	\
	interface name; 			\
	FULL_SMART_PTR(fbl_smart_value_ptr, name)


/**********************************************************************************************/
// Smart Array  pointers.
//
#define SMART_ARRAY( name, item_type ) \
	typedef Array<item_type> name; \
	FULL_SMART_PTR(smart_ptr, name)

#define SMART_ARRAY_OF_SIMPLES( name, item_type ) \
	typedef ArrayOfSimples<item_type> name; \
	FULL_SMART_PTR(smart_ptr, name)

#define SMART_ARRAY_OF_SIMPLE_PTRS( name, item_type ) \
	typedef ArrayOfPtrs<item_type> name; \
	FBL_SMART_PTR(name)

#define SMART_ARRAY_OF_CLASSES( name, item_type ) \
	typedef ArrayOfClasses<item_type> name; \
	FBL_SMART_PTR(name)

#define SMART_ARRAY_OF_CLASS_PTRS( name, item_type ) \
	typedef ArrayOfPtrs<item_type> name; \
	FBL_SMART_PTR(name)

#define SMART_ARRAY_OF_SMART_PTRS( name, item_type ) \
	typedef ArrayOfSmartPtrs<item_type> name; \
	FBL_SMART_PTR(name)


/**********************************************************************************************/
// Smart stack pointers.
//
#define SMART_STACK_OF_SIMPLE_PTRS( name, item_type ) \
	typedef Stack<item_type> name; \
	FBL_SMART_PTR(name)


/**********************************************************************************************/
// short Macro for std::auto_ptr
//
#define aptr std::auto_ptr


/**********************************************************************************************/
// Plugin macro
// Each Valentina plugin must have extention ".plugin";
// Each Valentina plugin must have exported C function with the specified name.
//
#define FBL_PLUGIN_EXTENTION "plugin"

#if FBL_UNIX || FBL_MAC_MACHO
#	define FBL_PLUGIN_INIT_FUNCTION "_Initialize"
#else // FBL_WIN || FBL_MAC
#	define FBL_PLUGIN_INIT_FUNCTION "Initialize"
#endif // FBL_UNIX


/**********************************************************************************************/
#define SIZE_OF_ARRAY(a) \
	sizeof(a) / sizeof(a[0])

/**********************************************************************************************/
#define ZERO(x) \
	memset(&(x), 0, sizeof(x));


/**********************************************************************************************/
// IF we compile kernel for Application, e.g. Valentina Server,
// we do not need overhead from support of ForeignPlugin, 
// then for such project this macro can be set to 1.
//
#ifndef FBL_Skip_ForeignPlugin
#	define FBL_Skip_ForeignPlugin 0 
#endif 


/**********************************************************************************************/
// Define this to allow static linking with eXpat.
#ifndef XML_STATIC
	#define XML_STATIC
#endif // XML_STATIC


/**********************************************************************************************/
// VX - all-in-one Mac OS X framework

#ifndef SKW_VX
#define SKW_VX  0
#endif

#ifndef SKW_VX_TRANSACTIONS
#define SKW_VX_TRANSACTIONS  0
#endif

#ifndef SKW_VX_NO_PAINTLIB
#define SKW_VX_NO_PAINTLIB  0
#endif

#ifndef SKW_VX_NO_XML_DUMP
#define SKW_VX_NO_XML_DUMP  0
#endif

#ifndef SKW_VX_THREADSAFE
#define SKW_VX_THREADSAFE  0
#endif

#ifndef FBL_THREADSAFE
#define FBL_THREADSAFE  SKW_VX_THREADSAFE
#endif

#if FBL_THREADSAFE
	#define ADDREF(refs)	AtomicAdd(&((refs).mValue), 1UL)
	#define RELEASE(refs)	AtomicAdd(&((refs).mValue), -1UL)
#else
	#define ADDREF(refs)	(++((refs).mValue))
	#define RELEASE(refs)	(--((refs).mValue))
#endif

#define RETAIN ADDREF
#define Retain AddRef

#if __GNUC__
	#define FBL_INLINE(ret_type) static inline ret_type __attribute__((unused))
	#define FBL_INLINE_ATTR __attribute__((__always_inline__))
	#define FBL_ALIGNED(b) __attribute__((aligned(b)))
#else
	#define FBL_INLINE(ret_type) static inline ret_type
	#define FBL_INLINE_ATTR
	#define FBL_ALIGNED(b) /* FIX ME */
	#if FBL_THREADSAFE
		#warning FIX ME:  FBL_ALIGNED(b) is undefined for this compiler!
	#endif
#endif


/**********************************************************************************************/
#endif // _FBL_Macros_h
